﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ZombieMonkeys.Vibria.Logic
{
    public class PuzzleChecker
    {
        private static PuzzleChecker instance;

        public static PuzzleChecker Instance
        {
            get { return instance; }
            
        }

        public PuzzleChecker GetPuzzleChecker()
        { 
            if (instance == null)
            {
                instance = new PuzzleChecker();
            }
            return instance;
        }

        public bool Check(List<Square> squaresToCheck)
        {
            List<Square> tempRowValues = new List<Square>();
            List<Square> tempColValues = new List<Square>();
            List<Square> tempMiniGridValues = new List<Square>();
            
            string pattern;
            //Check the row
            for (int r = 0; r < 9; r++)
            {
                //remove numbers from the string and if all the numbers are removed, then the row is valid
                pattern = "123456789";
                tempRowValues = buildRowList(squaresToCheck, r);
                for (int i = 0; i < 9; i++)
                {
                    pattern.Replace(tempRowValues[i].GetValue(), string.Empty);
                }
                if (pattern.Length > 0)
                {
                    return false;
                }
            }
            //check the columns
            for (int c = 0; c < 9; c++)
            {
                pattern = "123456789";
                tempColValues = buildColList(squaresToCheck, c);
                for (int i = 0; i < 9; i++)
                {
                    pattern.Replace(tempColValues[i].GetValue(), string.Empty);
                }
                if (pattern.Length > 0)
                {
                    return false;
                }
            }
            //Check the minigrids
            for (int i = 0; i < 9; i++)
            {
                pattern = "123456789";
                for (int rr = 0; rr < 2; rr++)
                {
                    for (int cc = 0; cc < 2; cc++)
                    {
                        tempMiniGridValues = buildMiniGridList(squaresToCheck, rr, cc);
                        for (int j = 0; j < tempMiniGridValues.Count; j++)
                        {
                            pattern.Replace(tempMiniGridValues[j].GetValue(), string.Empty);
                        }
                    }
                }
                if (pattern.Length > 0)
                {
                    return false;
                }
            }
            //If it hasn't returned false yet, then it must be a valid solution
            return true;
        }

        //if we want to do real time checking of the puzzle then we should have an Update like this
        public void Update(Puzzle puzzle)
        { 
            //i suppose we will do the entire checking logic in this  call, we may have to multithread this
            //if that is the case I might need some help on that, I have very little experience with multithreading
        }

        private void checkGroups(Puzzle puzzle)
        { 
            //check the groups
            for (int i = 0; i < puzzle.Grid.SquareList.Count; i++)
            {
                
            }
        }

        private void checkRows(Puzzle puzzle)
        {
            for (int i = 0; i < puzzle.Grid.SquareList.Count; i++)
            {
                
            }
        }

        private void checkColumns(Puzzle puzzle)
        {
            for (int i = 0; i < puzzle.Grid.SquareList.Count; i++)
            {
                
            }
        }

        private List<Square> buildRowList(List<Square> tempSquares, int rowIndex)
        {
            List<Square> rowValues = new List<Square>();
            for (int i = 0; i < tempSquares.Count; i++)
            {
                if (tempSquares[i].GetRow() == rowIndex)
                {
                    rowValues.Add(tempSquares[i]);
                }
            }
            
            return rowValues;
        }

        private List<Square> buildColList(List<Square> tempSquares, int colIndex)
        {
            List<Square> colValues = new List<Square>();
            for (int i = 0; i < tempSquares.Count; i++)
            {
                if (tempSquares[i].GetColumn() == colIndex)
                {
                    colValues.Add(tempSquares[i]);
                }
            }

            return colValues;
        }

        /// <summary>
        /// Creates a list of values in the miniGrid
        /// </summary>
        /// <param name="tempSquares">list of squares</param>
        /// <param name="miniGridIndexX">value from 0 to 2</param>
        /// <param name="miniGridIndexY">value from 0 to 2</param>
        /// <returns>List of Squares</returns>
        private List<Square> buildMiniGridList(List<Square> tempSquares, int miniGridIndexX, int miniGridIndexY)
        {
            List<Square> miniGridValues = new List<Square>();
            int lowerX = miniGridIndexX * 3;
            int upperX = lowerX + 3;
            int lowerY = miniGridIndexY * 3;
            int upperY = lowerY + 3;

            for (int r = lowerX; r < upperX; r++)
            {
                for (int c = lowerY; c < upperY; c++)
                {
                    for (int i = 0; i < tempSquares.Count; i++)
                    {
                        if (tempSquares[i].GetRow() == r && tempSquares[i].GetColumn() == c)
                        {
                            miniGridValues.Add(tempSquares[i]);
                        }
                    }
                }
            }
            return miniGridValues;
        }
        
    }
}
